package com.zf.shuashua.manager;

import android.app.Activity;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.zf.shuashua.ShuaApplication;
import com.zf.shuashua.api.Store;

import java.lang.ref.WeakReference;

/**
 * 定位
 */
public class LocationManager {

    private LocationClient mLocClientOne = null;
    private WeakReference<Activity> weakReference;
    private LocationListener locationListener;

    private static LocationManager instance;

    private LocationManager() {

    }

    public static LocationManager getInstance() {
        if (null == instance) {
            synchronized (LocationManager.class) {
                if (null == instance) {
                    instance = new LocationManager();
                }
            }
        }
        return instance;
    }

    public void startLocation(Activity activity, LocationListener locationListener) {
        this.weakReference = new WeakReference<>(activity);
        this.locationListener = locationListener;
        startOneLocation();
    }

    /**
     * 启动单次定位
     */
    private void startOneLocation() {
        mLocClientOne = new LocationClient(ShuaApplication.getContext());
        mLocClientOne.registerLocationListener(oneLocationListener);
        LocationClientOption locationClientOption = new LocationClientOption();
        // 可选，设置定位模式，默认高精度 LocationMode.Hight_Accuracy：高精度；
        locationClientOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        // 可选，设置返回经纬度坐标类型，默认GCJ02
        locationClientOption.setCoorType("bd09ll");
        // 如果设置为0，则代表单次定位，即仅定位一次，默认为0
        // 如果设置非0，需设置1000ms以上才有效
        locationClientOption.setScanSpan(0);
        // 设置是否进行单次定位，单次定位时调用start之后会默认返回一次定位结果
        locationClientOption.setOnceLocation(true);
        //可选，设置是否使用gps，默认false
        locationClientOption.setOpenGps(true);
        // 可选，是否需要地址信息，默认为不需要，即参数为false
        // 如果开发者需要获得当前点的地址信息，此处必须为true
        locationClientOption.setIsNeedAddress(true);
        // 设置定位参数
        mLocClientOne.setLocOption(locationClientOption);
        // 开启定位
        mLocClientOne.start();
    }

    private void dealLocationFail() {
        if (weakReference != null && locationListener != null) {
            weakReference.get().runOnUiThread(() -> {
                locationListener.onFail();
                stopOneLocation();
            });
        }
    }

    private void dealLocationSuccess(String city) {
        if (weakReference != null && locationListener != null) {
            weakReference.get().runOnUiThread(() -> {
                locationListener.onSuccess(city);
                stopOneLocation();
                Store.getInstance().setLastLocation(city);
            });
        }
    }

    /**
     * 停止单次定位
     */
    private void stopOneLocation() {
        if (null != mLocClientOne) {
            mLocClientOne.stop();
        }
    }

    /**
     * 单次定位回调监听
     */
    private BDAbstractLocationListener oneLocationListener = new BDAbstractLocationListener() {

        /**
         * 定位请求回调函数
         * @param location 定位结果
         */
        @Override
        public void onReceiveLocation(BDLocation location) {
            if (null == location) {
                dealLocationFail();
                return;
            }
            //TypeServerError:服务端网络定位失败
            //TypeNetWorkException:网络不同导致定位失败，请检查网络是否通畅
            //TypeCriteriaException:无法获取有效定位依据导致定位失败，一般是由于手机的原因，处于飞行模式下一般会造成这种结果，可以试着重启手机
            if (location.getLocType() == BDLocation.TypeServerError || location.getLocType() == BDLocation.TypeNetWorkException
                    || location.getLocType() == BDLocation.TypeCriteriaException) {
                dealLocationFail();
                return;
            }
            String city = location.getCity();    //获取城市
            dealLocationSuccess(city);
        }
    };
}
